/**
 * Thinking in java 
 *  2018/08/01
 */
package com.dzb.aioclient;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch;

/**
 * @author dzb
 * @date 2018年8月15日 下午6:12:40
 * @description  
 * @version 1.0.0
 */
public class AsyncTimeClientHandler  implements CompletionHandler<Void, AsyncTimeClientHandler>,Runnable{
	
	private String  host ="127.0.0.1";
	
	private int port =8080;
	
	private  AsynchronousSocketChannel  clientChannel;
	
	private CountDownLatch latch;
	
	/**
	 * 
	 */
	public AsyncTimeClientHandler(String host,int port) {
		this.host=host;
		this.port=port;
		try {
			clientChannel = AsynchronousSocketChannel.open();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	@Override
	public void run() {
		try {
			latch = new CountDownLatch(1);
			clientChannel.connect(new InetSocketAddress(host, port), this, this);
				latch.await();
			//保证执行完，才能结束
			clientChannel.close();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}



	
	@Override
	public void completed(Void result, AsyncTimeClientHandler attachment) {
		byte[] req ="现在传输附件，send this message".getBytes();//请求消息体
		ByteBuffer writebuffer = ByteBuffer.allocate(req.length);
		 writebuffer.put(req);
		 writebuffer.flip();
		 clientChannel.write(writebuffer, writebuffer, new CompletionHandler<Integer, ByteBuffer>() {
			@Override
			public void completed(Integer result, ByteBuffer buffer) {
				//如果发送缓冲区仍有尚未发送的字节，将继续异步发送。
				if(buffer.hasRemaining()){
					clientChannel.read(buffer, buffer, this);
				}else{
					//应答消息的处理逻辑
					ByteBuffer readbuffer = ByteBuffer.allocate(1024);
					//异步读取服务端的响应消息
					clientChannel.write(readbuffer, readbuffer, new CompletionHandler<Integer, ByteBuffer>() {
						@Override
						public void completed(Integer result, ByteBuffer buffer) {
							buffer.flip();
							byte[] bytes = new byte[buffer.remaining()];
							buffer.get(bytes);
							String  body;
							//打印结果
							try {
								body = new String(bytes,"UTF-8");
								System.out.println("call back  function body :"+new String(body));
								latch.countDown();
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
							}
							
						}

						@Override
						public void failed(Throwable exc, ByteBuffer attachment) {
							try {
								clientChannel.close();
								latch.countDown();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					});
				}
			}

			@Override
			public void failed(Throwable exc, ByteBuffer attachment) {
				try {
					clientChannel.close();
					latch.countDown();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
	}

	
	@Override
	public void failed(Throwable exc, AsyncTimeClientHandler attachment) {
		exc.printStackTrace();
		try {
			clientChannel.close();
			latch.countDown();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
